package com.voodoo.lib_utils;

import android.text.TextUtils;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Author: voodoo
 * CreateDate: 2019/08/29 029 下午 05:35:57
 * Description: Json解析工具类
 * json2Model(String jsonData, Class<T> type)
 * jsonArray2ModelList(String jsonData, Class<T> type)
 * model2Json(T entity)
 * ListtoString(List<T> entity)
 * list2JsonArrayNotNulls(List<T> list)
 * list2JsonArrayWithExpose(List<T> list)
 * MapToJson(Map<T, T> list)
 * StringMapToJson(Map<String, Object> coflist)
 */
public class GsonUtils {

    /**
     * JSONObject
     */
    public static final int JSON_TYPE_OBJECT = 1;
    /**
     * JSONArray
     */
    public static final int JSON_TYPE_ARRAY = 2;
    /**
     * 不是JSON格式的字符串
     */
    public static final int JSON_TYPE_ERROR = 3;

    /**
     * 将Json数据解析成相应的映射对象
     *
     * @param jsonData
     * @param type
     * @param <T>
     * @return
     */
    public static <T> T json2Model(String jsonData, Class<T> type) {
        T result = null;
        if (!jsonData.isEmpty()) {
            Gson gson = new GsonBuilder().create();

            try {
                result = gson.fromJson(jsonData, type);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (gson != null) {
                    gson = null;
                }
            }
        }

        return result;
    }

    /**
     * 将Json数组解析成相应的映射对象List
     *
     * @param jsonData
     * @param type
     * @param <T>
     * @return
     */
    public static <T> List<T> jsonArray2ModelList(String jsonData, Class<T> type) {
        List<T> result = null;
        if (!TextUtils.isEmpty(jsonData)) {
            Gson gson = new GsonBuilder().create();
            try {
                JsonParser parser = new JsonParser();
                JsonArray Jarray = parser.parse(jsonData).getAsJsonArray();
                if (Jarray != null) {
                    result = new ArrayList<>();
                    for (JsonElement obj : Jarray) {
                        try {
                            T cse = gson.fromJson(obj, type);
                            result.add(cse);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (gson != null) {
                    gson = null;
                }
            }
        }
        return result;
    }

    /**
     * 将对象转换成Json
     *
     * @param entity
     * @param <T>
     * @return
     */
    public static <T> String model2Json(T entity) {
        entity.getClass();
        Gson gson = new GsonBuilder().serializeNulls().create();
        String result = "";
        try {
            result = gson.toJson(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (gson != null) {
                gson = null;
            }
        }
        return result;
    }

    /**
     * 集合变成字符串
     *
     * @param entity
     * @param <T>
     * @return
     */
    public static <T> String ListtoString(List<T> entity) {
        entity.getClass();
        Gson gson = new GsonBuilder().serializeNulls().create();
        String result = "";
        try {
            result = gson.toJson(entity);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (gson != null) {
                gson = null;
            }
        }
        return result;
    }

    /**
     * 将list排除值为null的字段转换成Json数组
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> String list2JsonArrayNotNulls(List<T> list) {
        Gson gson = new GsonBuilder().serializeNulls().create();
        String result = "";
        try {
            result = gson.toJson(list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (gson != null) {
                gson = null;
            }
        }
        return result;
    }

    /**
     * 将list中将Expose注解的字段转换成Json数组
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> String list2JsonArrayWithExpose(List<T> list) {
        Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
        String result = "";
        try {
            result = gson.toJson(list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (gson != null) {
                gson = null;
            }
        }
        return result;
    }

    /**
     * 将list排除值为null的字段转换成Json数组
     *
     * @param list
     * @param <T>
     * @return
     */
    public static <T> String MapToJson(Map<T, T> list) {
        Gson gson = new GsonBuilder().serializeNulls().create();
        String result = "";
        try {
            result = gson.toJson(list);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (gson != null) {
                gson = null;
            }
        }
        return result;
    }

    /**
     * Map转换成Json
     */
    public static String StringMapToJson(Map<String, Object> coflist) {

        Gson gson = new GsonBuilder().serializeNulls().create();
        String result = "";
        try {
            result = gson.toJson(coflist);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (gson != null) {
                gson = null;
            }
        }
        return result;

    }

    // ===================================== 直接对JSON进行操作 =====================================

    /**
     * json 转换成Map-List集合
     *
     * @param json json
     * @return Map-List集合
     */
    public static List<Object> json2MapList(String json) {
        List<Object> mapList = null;
        try {
            if (getJSONType(json) == JSON_TYPE_OBJECT) {
                JSONObject jsonObject = new JSONObject(json);
                Map<String, Object> objects = reflect(jsonObject);
                mapList = new ArrayList<>();
                mapList.add(objects);
            } else if (getJSONType(json) == JSON_TYPE_ARRAY) {
                JSONArray jsonArray = new JSONArray(json);
                mapList = reflect(jsonArray);
            } else {
                Log.e("smartTable", "json异常");
            }

        } catch (JSONException e) {
            e.printStackTrace();
        }
        return mapList;
    }

    /**
     * 将JSONObjec对象转换成Map-List集合
     *
     * @param json
     * @return
     */
    public static Map<String, Object> reflect(JSONObject json) {
        HashMap<String, Object> map = new LinkedHashMap<>();
        Iterator<String> keys = json.keys();
        try {
            for (; keys.hasNext(); ) {
                String key = keys.next();
                Object o = json.get(key);
                if (o instanceof JSONArray)
                    map.put(key, reflect((JSONArray) o));
                else if (o instanceof JSONObject)
                    map.put(key, reflect((JSONObject) o));
                else
                    map.put(key, o);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return map;
    }

    /**
     * 将JSONArray对象转换成Map-List集合
     *
     * @param json
     * @return
     */
    public static List<Object> reflect(JSONArray json) {
        List<Object> list = new ArrayList<>();
        try {
            for (int i = 0; i < json.length(); i++) {
                Object o = json.get(i);
                if (o instanceof JSONArray)
                    list.add(reflect((JSONArray) o));
                else if (o instanceof JSONObject)
                    list.add(reflect((JSONObject) o));
                else
                    list.add(o);
            }
        } catch (JSONException e) {
            e.printStackTrace();
        }
        return list;
    }

    /***
     * 获取JSON类型 JsonArray还是JsonObject或者不是Json格式的字符串
     */
    private static int getJSONType(String str) {
        if (TextUtils.isEmpty(str)) {
            return JSON_TYPE_ERROR;
        }
        char[] strChar = str.substring(0, 1).toCharArray();
        char firstChar = strChar[0];

        if (firstChar == '{') {
            return JSON_TYPE_OBJECT;
        } else if (firstChar == '[') {
            return JSON_TYPE_ARRAY;
        } else {
            return JSON_TYPE_ERROR;
        }
    }
    // =================================== 直接对JSON进行操作 完 ====================================

}
